//  Author:
//       Daniel Großer <olav.daniel.grosser@googlemail.com>
//  
//  Copyright (c) 2012 Copyright (C) 2012 by Daniel Großer. This Code is under GNU LGPL 3.0
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
// 
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Text.RegularExpressions;

namespace Beauty
{
    /// <summary>
    /// A RegEx terminal is a terminal specified by regular expression. You will typically
    /// use this for identifiers, string literals and the like.
    /// </summary>
    /// <example>
    /// <code>
    /// [RegExTerminal(@"[A-Za-z]+([A-Za-z0-9])*")]
    /// public string Identifier { get; set; }
    /// </code>
    /// </example>
    public sealed class RegExTerminalAttribute : TerminalAttribute
    {
        /// <summary>
        /// Create a new terminal denoted by a regex.
        /// </summary>
        /// <param name="regex">The regular expression. (Without leading ^ or trailing $)</param>
        public RegExTerminalAttribute(string regex)
        {
            StringTerminal = regex;
            RegularExpression = new Regex("^" + regex);
        }

        /// <summary>
        /// Get the regular expression modelling the terminal.
        /// </summary>
        public Regex RegularExpression { get; private set; }

        /// <summary>
        /// Try to match the RegEx at the very start of a string.
        /// </summary>
        /// <param name="input">The string to match.</param>
        /// <returns>A value greater 0 iff match is successful, where the return value equals the matched length.</returns>
        public override int MatchStart(string input)
        {
            var match = RegularExpression.Match(input);
            if (match.Success)
                return match.Length;
            else
                return 0;
        }
		
		/// <summary>
		/// Gets the scanner-precedence value. Terminals with a lower
		/// value will be preferred by the scanner. Among a set of
		/// equal-precedence terminals, the longest match will win.
		/// </summary>
		/// <value>
		/// 2, because regexes can be parsed at last.
		/// </value>
		public override byte ScannerPrecedence { get { return PRECEDENCE; } }		
		
        /// <summary>
        /// Return a string representation.
        /// </summary>
        /// <returns>The string representation.</returns>
        public override string ToString()
        {
            return string.Format("RegEx Terminal \"{0}\"", RegularExpression);			
        }
		
		/// <summary>
		/// The scanner precedence of Regular Expression Terminals.
		/// </summary>
		public const byte PRECEDENCE = 2;
    }
}
